package org.interfaceadaptation.parameter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;

import javax.ws.rs.QueryParam;

import com.thoughtworks.paranamer.BytecodeReadingParanamer;
import com.thoughtworks.paranamer.Paranamer;

public class Parameters extends ArrayList<Parameter> {

    private static final long serialVersionUID = 1L;

    public Parameters(Method method) {
        Parameter parameter;
        String[] parameterNames = getParameterNames(method);
        String[] restParameterNames = getRestParameterNames(method);
        boolean allRestParameterNamesNull = checkAllNull(restParameterNames);
        for (int i = 0; i < method.getParameterTypes().length; i++) {
            if (allRestParameterNamesNull) {
            parameter =
                    new Parameter(method.getParameterTypes()[i],
                            parameterNames[i]);
            }
            else {
                parameter =
                    new Parameter(method.getParameterTypes()[i],
                            parameterNames[i], restParameterNames[i]);
                
            }
            add(parameter);
        }
    }

    private boolean checkAllNull(String[] restParameterNames) {
        for(String restParameterName:restParameterNames) {
            if (restParameterName != null) {
                return false;
            }
        }
        return true;
    }

    private String[] getParameterNames(Method method) {
        Paranamer paranamer = new BytecodeReadingParanamer();
        String[] parameterNames = paranamer.lookupParameterNames(method, false);
        if (parameterNames == null) {
            parameterNames = new String[method.getParameterTypes().length];
            for (int i = 0; i < method.getParameterTypes().length; i++) {
                parameterNames[i] = "[" + i + "]";
            }
        }
        return parameterNames;
    }

    private String[] getRestParameterNames(Method method) {
        Annotation[][] annotations = method.getParameterAnnotations();

        String[] parameterNames = new String[method.getParameterTypes().length];
        for (int j = 0; j < annotations.length; j++) {
            for (int i = 0; i < annotations[j].length; i++) {
                Annotation paramAnnotation = annotations[j][i];
                if (paramAnnotation instanceof QueryParam) {
                    parameterNames[j] = ((QueryParam) paramAnnotation).value();
                }
            }
        }

        return parameterNames;
    }

}
